package com.coinworld.utils;

import com.alibaba.fastjson.JSONObject;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.Response;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import java.io.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * 网络相关操作工具
 *                       
 * @Filename: HttpUtil.java
 * @Version: 1.0
 * @Author: zhaihl
 * @Email: zhaihl_0@126.com
 *
 */
@SuppressWarnings("rawtypes")
public class HttpUtil {
    private static final String DEFAULT_CHARSET = "UTF-8";
    private static final String GBK_CHARSET = "GB2312";
    /**
     * 消息操作接口
     */
//    public static final Message message         = new Message();

    /**
     * 获取access_token
     *
     * @return
     * @throws Exception
     */
    public static String getAccessToken() throws Exception {
        String appid = WxPayConfig.WXPAY_APPID;
        String secret = WxPayConfig.WXPAY_APPSECRET;
        String jsonStr = HttpUtil.get(WxPayConfig.WXPAY_ACCESS_TOKEN.concat("&appid=") + appid
                                      + "&secret=" + secret);
        Map<String, Object> map = JSONObject.parseObject(jsonStr);
        return map.get("access_token") == null ? null : map.get("access_token").toString();
    }






    public static String getJsTicket(String accessToken) throws Exception {
        String jsonStr = HttpUtil.get(String.format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi",accessToken));
        Map<String, Object> map = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
        return map.get("ticket") == null ? null : map.get("ticket").toString();
    }
//    public static String createQrcode(Integer scene_id,String accessToken) throws Exception{
//    	JSONObject jsonObject = new JSONObject();
//    	jsonObject.put("expire_seconds",CommonPropertyFactoryUtil.EXPIRE_SECONDS);
//    	jsonObject.put("action_name", CommonPropertyFactoryUtil.ACTION_NAME);
////    	jsonObject.put("expire_seconds",PropertyFactory.getProperty("EXPIRE_SECONDS"));
////    	jsonObject.put("action_name", PropertyFactory.getProperty("ACTION_NAME"));
////    	jsonObject.put("expire_seconds","604800");
////    	jsonObject.put("action_name", "QR_SCENE");
//    	JSONObject actionInfo = new JSONObject();
//    	JSONObject sceneId = new JSONObject();
//    	sceneId.put("scene_id", scene_id);
//    	actionInfo.put("scene", sceneId);
//    	jsonObject.put("action_info", actionInfo);
//
//    	String jsonStr = HttpUtil.post(String.format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s",accessToken),jsonObject.toJSONString());
//        Map<String, Object> map = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
//        return map.get("url") == null ? null : map.get("url").toString();
//    }
    public static Map<String, Object> getUserInfo(String openId,String accessToken) throws Exception{
    	String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken +"&openid="+openId+"&lang=zh_CN";
    	String jsonStr = HttpUtil.get(url);
        Map<String, Object> map = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
        return map;
    }

    public static void main(String[] args) {
    	try {
    		Map<String, Object> resultMap = getUserInfo("ogUFp0UdFUID2d1uA_cnmUtpFnUw","6_g2zPsgqLXPRaL2rNP7NH9yKf2xAlffX-ZvtFHjfvoPX6GrEzqwMy45CUoxk7ib19Sk0OMd-ki9G5CXYrNHiVla5vETGR6kCjTRA-jHAi8CjVg73NUx9txWpLafwLLLdABAHHH");
    		Integer subscribe = (Integer) resultMap.get("subscribe");
			String openid = (String) resultMap.get("openid");
			String nickname = (String)resultMap.get("nickname");
			Integer sex = (Integer)resultMap.get("sex");
			String language = (String)resultMap.get("language");
			String city = (String)resultMap.get("city");
			String province = (String)resultMap.get("province");
			String country = (String)resultMap.get("country");
			String headimgurl = (String)resultMap.get("headimgurl");
			Integer subscribe_time = (Integer)resultMap.get("subscribe_time");
			String unionid = (String)resultMap.get("unionid");
			
			
//			Date date1 = new Date(date);
//			System.out.println(date1);
//			String remark = (String)resultMap.get("remark");
//			Integer groupid = (Integer)resultMap.get("groupid");
//			List tagid_list = (List) resultMap.get("tagid_list");
//			System.out.println(tagid_list.toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
    /**
     * @return 返回类型:
     * @throws IOException
     * @throws UnsupportedEncodingException
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @description 功能描述: get 请求
     */
    public static String get(String url, Map<String, String> params, Map<String, String> headers)
                                                                                                 throws IOException,
                                                                                                 ExecutionException,
                                                                                                 InterruptedException {
        AsyncHttpClient http = new AsyncHttpClient();
        AsyncHttpClient.BoundRequestBuilder builder = http.prepareGet(url);
        builder.setBodyEncoding(DEFAULT_CHARSET);
        if (params != null && !params.isEmpty()) {
            Set<String> keys = params.keySet();
            for (String key : keys) {
                builder.addQueryParameter(key, params.get(key));
            }
        }

        if (headers != null && !headers.isEmpty()) {
            Set<String> keys = headers.keySet();
            for (String key : keys) {
                builder.addHeader(key, params.get(key));
            }
        }
        Future<Response> f = builder.execute();
        String body = f.get().getResponseBody(DEFAULT_CHARSET);
        http.close();
        return body;
    }

    /**
     * @return 返回类型:
     * @throws IOException
     * @throws UnsupportedEncodingException
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @description 功能描述: get 请求
     */
    public static String get(String url) throws KeyManagementException, NoSuchAlgorithmException,
                                        NoSuchProviderException, UnsupportedEncodingException,
                                        IOException, ExecutionException, InterruptedException {
        return get(url, null);
    }

    /**
     * @return 返回类型:
     * @throws IOException
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @throws UnsupportedEncodingException
     * @description 功能描述: get 请求
     */
    public static String get(String url, Map<String, String> params) throws KeyManagementException,
                                                                    NoSuchAlgorithmException,
                                                                    NoSuchProviderException,
                                                                    UnsupportedEncodingException,
                                                                    IOException,
                                                                    ExecutionException,
                                                                    InterruptedException {
        return get(url, params, null);
    }

    /**
     * @return 返回类型:
     * @throws IOException
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @description 功能描述: POST 请求
     */
    public static String post(String url, Map<String, String> params, Map<String, String> headers) throws IOException,
                                                                     ExecutionException,
                                                                     InterruptedException {
        AsyncHttpClient http = new AsyncHttpClient();
        AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);
        builder.setBodyEncoding(DEFAULT_CHARSET);
        if (params != null && !params.isEmpty()) {
            Set<String> keys = params.keySet();
            for (String key : keys) {
                builder.addParameter(key, params.get(key));
            }
        }
        if (headers != null && !headers.isEmpty()) {
            Set<String> keys = headers.keySet();
            for (String key : keys) {
                builder.addHeader(key, params.get(key));
            }
        }
        Future<Response> f = builder.execute();
        String body = f.get().getResponseBody(DEFAULT_CHARSET);
        http.close();
        return body;
    }

    /**
     * @return 返回类型:
     * @throws IOException
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @description 功能描述: POST 请求
     */
    public static String post(String url, Map<String, String> params) throws IOException,
            ExecutionException,
            InterruptedException {
        AsyncHttpClient http = new AsyncHttpClient();
        AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);
        builder.setBodyEncoding(DEFAULT_CHARSET);
        if (params != null && !params.isEmpty()) {
            Set<String> keys = params.keySet();
            for (String key : keys) {
                builder.addParameter(key, params.get(key));
            }
        }
        Future<Response> f = builder.execute();
        String body = f.get().getResponseBody(DEFAULT_CHARSET);
        http.close();
        return body;
    }

    /**
     * @return 返回类型:
     * @throws IOException
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @description 功能描述: POST 请求 字符编码GBK
     */
    public static String postGBK(String url, Map<String, String> params) throws IOException,
            ExecutionException,
            InterruptedException {
        AsyncHttpClient http = new AsyncHttpClient();
        AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);
        builder.setBodyEncoding(GBK_CHARSET);
        if (params != null && !params.isEmpty()) {
            Set<String> keys = params.keySet();
            for (String key : keys) {
                builder.addParameter(key, params.get(key));
            }
        }
        Future<Response> f = builder.execute();
        String body = f.get().getResponseBody(GBK_CHARSET);
        http.close();
        return body;
    }


    public static String post(String url, String s) throws IOException, ExecutionException,
                                                   InterruptedException {
        AsyncHttpClient http = new AsyncHttpClient();
        AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);
        builder.setBodyEncoding(DEFAULT_CHARSET);
        builder.setBody(s);
        Future<Response> f = builder.execute();
        String body = f.get().getResponseBody(DEFAULT_CHARSET);
        http.close();
        return body;
    }

//    /**
//     * 发送https请求
//     *
//     * @param requestUrl 请求地址
//     * @param requestMethod 请求方式（GET、POST）
//     * @param outputStr 提交的数据
//     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
//     */
//    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
//        JSONObject jsonObject = null;
//        try {
//            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
//            TrustManager[] tm = { new MyX509TrustManager() };
//            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
//            sslContext.init(null, tm, new java.security.SecureRandom());
//            // 从上述SSLContext对象中得到SSLSocketFactory对象
//            SSLSocketFactory ssf = sslContext.getSocketFactory();
//
//            URL url = new URL(requestUrl);
//            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
//            conn.setSSLSocketFactory(ssf);
//
//            conn.setDoOutput(true);
//            conn.setDoInput(true);
//            conn.setUseCaches(false);
//            // 设置请求方式（GET/POST）
//            conn.setRequestMethod(requestMethod);
//
//            // 当outputStr不为null时向输出流写数据
//            if (null != outputStr) {
//                OutputStream outputStream = conn.getOutputStream();
//                // 注意编码格式
//                outputStream.write(outputStr.getBytes("UTF-8"));
//                outputStream.close();
//            }
//
//            // 从输入流读取返回内容
//            InputStream inputStream = conn.getInputStream();
//            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
//            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
//            String str = null;
//            StringBuffer buffer = new StringBuffer();
//            while ((str = bufferedReader.readLine()) != null) {
//                buffer.append(str);
//            }
//
//            // 释放资源
//            bufferedReader.close();
//            inputStreamReader.close();
//            inputStream.close();
//            inputStream = null;
//            conn.disconnect();
//            jsonObject = JSONObject.parseObject(buffer.toString());
//        } catch (ConnectException ce) {
//        } catch (Exception e) {
//        }
//        return jsonObject;
//    }

    public static synchronized String getPayNo(String url, String xmlParam) throws Exception {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            httpclient = HttpClients.createDefault();
            httpPost.setEntity(new StringEntity(xmlParam, "UTF-8"));
            response = httpclient.execute(httpPost);
            String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");

//            System.out.println("jsonStr==============\n" + jsonStr);
//            Map<String, String> map = doXMLParse(jsonStr);
//
//            if (!"SUCCESS".equals(map.get("return_code"))) {
//                throw new RuntimeException(map.get("return_msg"));
//            }
            return jsonStr;
        } finally {
            if (httpclient != null) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点，则此节点的值是子节点的xml数据。
     * @param strxml
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static Map<String, String> doXMLParse(String strxml) throws Exception {
        if (null == strxml || "".equals(strxml)) {
            return null;
        }

        Map<String, String> m = new HashMap<String, String>();
        InputStream in = String2Inputstream(strxml);
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List list = root.getChildren();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if (children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = getChildrenText(children);
            }

            m.put(k, v);
        }

        //关闭流
        in.close();

        return m;
    }

    /**
     * 获取子结点的xml
     * @param children
     * @return String
     */
    public static String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if (!children.isEmpty()) {
            Iterator it = children.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");
                if (!list.isEmpty()) {
                    sb.append(getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }

        return sb.toString();
    }

    public static InputStream String2Inputstream(String str) {
        return new ByteArrayInputStream(str.getBytes());
    }

    public static byte[] getWxCodeInputStream(String url, String jsonParamter) throws Exception {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            httpclient = HttpClients.createDefault();
            httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
            StringEntity entity = new StringEntity(jsonParamter);
            entity.setContentType("image/png");
            httpPost.setEntity(entity);
            response = httpclient.execute(httpPost);
            InputStream inputStream = response.getEntity().getContent();
            byte[] bytes = toByteArray(inputStream);


//            CommonTools.saveToImgByInputStream(inputStream,"D:\\",name);  //保存图片
            return bytes;
        } finally {
            if (httpclient != null) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }



    public static byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024*4];
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        }
        return output.toByteArray();
    }

    public static String requestByGet(String url,StringBuffer params){
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 创建Get请求
        HttpGet httpGet = new HttpGet(url + "?" + params);
        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 配置信息
            RequestConfig requestConfig = RequestConfig.custom()
                    // 设置连接超时时间(单位毫秒)
                    .setConnectTimeout(5000)
                    // 设置请求超时时间(单位毫秒)
                    .setConnectionRequestTimeout(5000)
                    // socket读写超时时间(单位毫秒)
                    .setSocketTimeout(5000)
                    // 设置是否允许重定向(默认为true)
                    .setRedirectsEnabled(true).build();

            // 将上面的配置信息 运用到这个Get请求里
            httpGet.setConfig(requestConfig);

            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpGet);

            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                String content = EntityUtils.toString(responseEntity);
                return content;
            }else{
                return null;
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            return null;
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
